#pragma once

namespace rpc {

// singleton
template <typename ClassType>
class Singleton {
    Singleton() = delete;
    Singleton(const Singleton&) = delete;
    Singleton(Singleton&&) = delete;
    Singleton<ClassType>& operator=(const Singleton&) = delete;

private:
    static ClassType* instance_; // The pointer of Singleton

public:
    // Returns the singleton instance pointer
    // @param args The argument for ctor of ClassType
    // @return singleton instance pointer
    template <typename...Args>
    static ClassType* instance(Args&&...args) {
        if (!instance_) {
            instance_ = new ClassType(std::forward<Args>(args)...);
        }
        return instance_;
    }

    // Destroy singleton
    static void destroy() {
        if (instance_) {
            delete instance_;
        }
        instance_ = nullptr;
    }
};

template <typename T> T *Singleton<T>::instance_ = nullptr;

}
